/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainPanel.java
 *
 * Created on Dec 22, 2009, 3:58:42 PM
 */
package jmxlogger.tools.console;

import java.awt.Color;
import java.awt.Cursor;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import jmxlogger.tools.JmxLogEmitterMBean;
import jmxlogger.tools.ToolBox;

/**
 *
 * @author vvivien
 */
public class MainPanel extends javax.swing.JPanel {

    private ClientService clientService;
    private JmxLogEmitterMBean logEmitter;
    private String lineSep = System.getProperty("line.separator");
    private volatile boolean connected = false;
    private volatile boolean logging = true;

    /** Creates new form MainPanel */
    public MainPanel() {
        initComponents();
        initializePanel();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        connectionDialog = new javax.swing.JDialog();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        txtAddress = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        txtUsername = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        txtPassword = new javax.swing.JPasswordField();
        btnConnect = new javax.swing.JButton();
        jLabel4 = new javax.swing.JLabel();
        txtMBeanName = new javax.swing.JTextField();
        jPanel1 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        txtFilterLevel = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        txtFilterExpression = new javax.swing.JTextArea();
        bthSave = new javax.swing.JButton();
        jToolBar1 = new javax.swing.JToolBar();
        btnShowConnDialog = new javax.swing.JButton();
        btnDisconnect = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        btnGo = new javax.swing.JButton();
        btnPause = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        btnRefresh = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtLogText = new javax.swing.JTextPane();

        connectionDialog.setTitle("Connect to MBean Server");
        connectionDialog.setIconImage(null);
        connectionDialog.setLocationByPlatform(true);
        connectionDialog.setMinimumSize(new java.awt.Dimension(402, 225));
        connectionDialog.setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL);
        connectionDialog.setName("connectionDialog"); // NOI18N
        connectionDialog.setResizable(false);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Connection Settings"));

        jLabel1.setText("Address:");

        txtAddress.setText("localhost:1099");
        txtAddress.setToolTipText("Enter MBeanServer Address");

        jLabel2.setText("Username:");

        txtUsername.setToolTipText("Enter JMX Username (if needed)");
        txtUsername.setPreferredSize(new java.awt.Dimension(30, 20));

        jLabel3.setText("Password:");

        txtPassword.setToolTipText("Enter Password");
        txtPassword.setMinimumSize(new java.awt.Dimension(30, 20));
        txtPassword.setPreferredSize(new java.awt.Dimension(30, 20));

        btnConnect.setText("Connect");
        btnConnect.setToolTipText("Connect to Log Emitter Agent");
        btnConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConnectActionPerformed(evt);
            }
        });

        jLabel4.setText("MBean:");

        txtMBeanName.setText("jmxlogger:type=LogEmitter");
        txtMBeanName.setToolTipText("The MBean name of the LogEmitterMBean");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtMBeanName, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)
                            .addComponent(txtAddress, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                                .addComponent(txtUsername, javax.swing.GroupLayout.DEFAULT_SIZE, 165, Short.MAX_VALUE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel3)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(btnConnect))))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(txtAddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3)
                    .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(txtMBeanName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnConnect))
        );

        javax.swing.GroupLayout connectionDialogLayout = new javax.swing.GroupLayout(connectionDialog.getContentPane());
        connectionDialog.getContentPane().setLayout(connectionDialogLayout);
        connectionDialogLayout.setHorizontalGroup(
            connectionDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(connectionDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        connectionDialogLayout.setVerticalGroup(
            connectionDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(connectionDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        setName("mainPanel"); // NOI18N
        setPreferredSize(new java.awt.Dimension(640, 480));

        jPanel3.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jLabel5.setText("Log Level:");

        txtFilterLevel.setText("INFO");
        txtFilterLevel.setToolTipText("The log level used as filter");

        jLabel6.setText("Filter Expression");

        txtFilterExpression.setColumns(20);
        txtFilterExpression.setRows(5);
        txtFilterExpression.setToolTipText("Enter an expression used as filter");
        jScrollPane2.setViewportView(txtFilterExpression);

        bthSave.setText("Apply");
        bthSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bthSaveActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(txtFilterLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabel6)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 523, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(bthSave)))
                .addContainerGap(36, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(txtFilterLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(bthSave))
        );

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);

        btnShowConnDialog.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jmxlogger/tools/console/icons/network-receive.png"))); // NOI18N
        btnShowConnDialog.setToolTipText("Connect");
        btnShowConnDialog.setHideActionText(true);
        btnShowConnDialog.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnShowConnDialogActionPerformed(evt);
            }
        });
        jToolBar1.add(btnShowConnDialog);

        btnDisconnect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jmxlogger/tools/console/icons/network-offline.png"))); // NOI18N
        btnDisconnect.setToolTipText("Disconnect");
        btnDisconnect.setFocusable(false);
        btnDisconnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnDisconnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnDisconnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDisconnectActionPerformed(evt);
            }
        });
        jToolBar1.add(btnDisconnect);
        jToolBar1.add(jSeparator1);

        btnGo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jmxlogger/tools/console/icons/media-playback-start.png"))); // NOI18N
        btnGo.setToolTipText("Run Console Logging");
        btnGo.setFocusable(false);
        btnGo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnGo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnGo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGoActionPerformed(evt);
            }
        });
        jToolBar1.add(btnGo);

        btnPause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jmxlogger/tools/console/icons/media-playback-pause.png"))); // NOI18N
        btnPause.setToolTipText("Pause Console Logging");
        btnPause.setFocusable(false);
        btnPause.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnPause.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnPause.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPauseActionPerformed(evt);
            }
        });
        jToolBar1.add(btnPause);
        jToolBar1.add(jSeparator2);

        btnRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jmxlogger/tools/console/icons/view-refresh.png"))); // NOI18N
        btnRefresh.setToolTipText("Apply Values");
        btnRefresh.setActionCommand("Refresh");
        btnRefresh.setFocusable(false);
        btnRefresh.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnRefresh.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRefreshActionPerformed(evt);
            }
        });
        jToolBar1.add(btnRefresh);

        jScrollPane1.setViewportView(txtLogText);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 640, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 640, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 328, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void initializePanel() {
        connectionDialog.setLocationRelativeTo(this.getParent());
        connectionDialog.setVisible(false);
        connectionDialog.pack();

        clientService = new ClientService();
        clientService.setConnectionListener(new ClientConnectionListener() {

            @Override
            public void onConnectionOpened() {
                connected = true;
                logging = true;
                MainPanel.this.postAdvisory("Connection established with the server." + lineSep);
            }

            @Override
            public void onConnectionClosed() {
                connected = false;
                logging = false;
                MainPanel.this.postAdvisory("Connection to server closed." + lineSep);
            }

            @Override
            public void onConnectionFailed() {
                connected = false;
                logging = false;
                MainPanel.this.postAdvisory("Connection to server failed unexpectedly." + lineSep);
            }
        });
    }

    private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed
        connectionDialog.setVisible(false);
        setupConnection();
}//GEN-LAST:event_btnConnectActionPerformed

    private void btnShowConnDialogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowConnDialogActionPerformed
        if (!connected) {
            connectionDialog.setVisible(true);
        }
    }//GEN-LAST:event_btnShowConnDialogActionPerformed

    private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDisconnectActionPerformed
        if (connected) {
            tearDownConnection();
        }
    }//GEN-LAST:event_btnDisconnectActionPerformed

    private void btnGoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGoActionPerformed
        if (connected && !logging) {
            logging = true;
            postMessage("Running logging." + lineSep);
        }
    }//GEN-LAST:event_btnGoActionPerformed

    private void btnPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPauseActionPerformed
        if (connected && logging) {
            logging = false;
            postAdvisory("Logging paused." + lineSep);
        }
    }//GEN-LAST:event_btnPauseActionPerformed

    private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
        if (connected && logEmitter != null) {
            this.txtFilterLevel.setText(logEmitter.getLevel());
            this.txtFilterExpression.setText(logEmitter.getFilterExpression());
        }
    }//GEN-LAST:event_btnRefreshActionPerformed

    private void bthSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bthSaveActionPerformed
        if (connected && logEmitter != null) {
            logEmitter.setFilterExpression(txtFilterExpression.getText());
            logEmitter.setLevel(txtFilterLevel.getText());
        }
    }//GEN-LAST:event_bthSaveActionPerformed

    private void setupConnection() {
        String connId = null;
        try {
            this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            connId = clientService.connect(
                    this.txtAddress.getText(),
                    this.txtUsername.getText(),
                    new String(this.txtPassword.getPassword()));
        } catch (Exception ex) {
            connected = false;
            postAdvisory("Unable to connect MBean server: " + ex.getMessage()  + lineSep);
        } finally {
            this.setCursor(Cursor.getDefaultCursor());
        }

        if (connId != null) {
            connected = true;
            logging = true;

            postAdvisory("Connected: " + txtUsername.getText() + "@" + clientService.getServiceUrl() + lineSep);

            // get log emitter object
            logEmitter = clientService.getLogEmitter(ToolBox.buildObjectName(this.txtMBeanName.getText()));

            // update ui
            this.txtFilterLevel.setText(logEmitter.getLevel());
            this.txtFilterExpression.setText(logEmitter.getFilterExpression());

            // setup a listerer
            clientService.addListenerToLogEmitter(
                    ToolBox.buildObjectName(this.txtMBeanName.getText()),
                    new NotificationListener() {

                        @Override
                        public void handleNotification(Notification notification, Object handback) {
                            if (MainPanel.this.logging) {
                                try {
                                    Map<String, Object> data = (Map<String, Object>) notification.getUserData();
                                    String level = (String) data.get(ToolBox.KEY_EVENT_LEVEL);
                                    String formattedMsg = (String) data.get(ToolBox.KEY_EVENT_FORMATTED_MESSAGE);

                                    if (level.equalsIgnoreCase("FINE")
                                            || level.equalsIgnoreCase("FINER")
                                            || level.equalsIgnoreCase("FINEST")
                                            || level.equalsIgnoreCase("DEBUG")) {
                                        MainPanel.this.postChatter(formattedMsg);
                                    } else if (level.equalsIgnoreCase("INFO")) {
                                        MainPanel.this.postMessage(formattedMsg);
                                    } else if (level.equalsIgnoreCase("WARN")
                                            || level.equalsIgnoreCase("WARNING")
                                            || level.equalsIgnoreCase("CONFIG")) {
                                        MainPanel.this.postWarning(formattedMsg);
                                    } else if (level.equalsIgnoreCase("ERROR")
                                            || level.equalsIgnoreCase("SEVERE")
                                            || level.equalsIgnoreCase("FATAL")) {
                                        MainPanel.this.postAdvisory(formattedMsg);
                                    } else {
                                        MainPanel.this.postMessage(formattedMsg);
                                    }
                                    MainPanel.this.txtLogText.setCaretPosition(MainPanel.this.txtLogText.getDocument().getLength());
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            }
                        }
                    });
        }
    }

    public void tearDownConnection() {
        if (clientService != null && connected) {
            try {
                clientService.disconnect();
                connected = false;
                logging = false;
                postAdvisory("Disconnected from server @ " + clientService.getServiceUrl()  + lineSep);
            } catch (Exception ex) {
                postAdvisory("Unable to disconnect from MBean Server: " + ex.getMessage()  + lineSep);
            }
        }
    }

    private void postMessage(String msg) {
        StyledDocument doc = txtLogText.getStyledDocument();
        try {
            Style messageStyle = doc.addStyle("message", null);
            StyleConstants.setForeground(messageStyle, Color.BLUE);
            doc.insertString(doc.getLength(), msg, messageStyle);
        } catch (BadLocationException ex) {
            throw new RuntimeException("Unable to set message style in text pane: " + ex.getMessage());
        }
    }

    private void postWarning(String msg) {
        StyledDocument doc = txtLogText.getStyledDocument();
        try {
            Style messageStyle = doc.addStyle("warn", null);
            StyleConstants.setForeground(messageStyle, Color.ORANGE);
            doc.insertString(doc.getLength(), msg, messageStyle);
        } catch (BadLocationException ex) {
            throw new RuntimeException("Unable to set message style in text pane: " + ex.getMessage());
        }
    }

    private void postChatter(String msg) {
        StyledDocument doc = txtLogText.getStyledDocument();
        try {
            Style messageStyle = doc.addStyle("warn", null);
            StyleConstants.setForeground(messageStyle, Color.GRAY);
            doc.insertString(doc.getLength(), msg, messageStyle);
        } catch (BadLocationException ex) {
            throw new RuntimeException("Unable to set message style in text pane: " + ex.getMessage());
        }
    }

    private void postAdvisory(String err) {
        StyledDocument doc = txtLogText.getStyledDocument();
        try {
            Style advisoryStyle = doc.addStyle("advisory", null);
            StyleConstants.setForeground(advisoryStyle, Color.RED);
            doc.insertString(doc.getLength(), err, advisoryStyle);
        } catch (BadLocationException ex) {
            throw new RuntimeException("Unable to set message style in text pane: " + ex.getMessage());
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bthSave;
    private javax.swing.JButton btnConnect;
    private javax.swing.JButton btnDisconnect;
    private javax.swing.JButton btnGo;
    private javax.swing.JButton btnPause;
    private javax.swing.JButton btnRefresh;
    private javax.swing.JButton btnShowConnDialog;
    private javax.swing.JDialog connectionDialog;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JTextField txtAddress;
    private javax.swing.JTextArea txtFilterExpression;
    private javax.swing.JTextField txtFilterLevel;
    private javax.swing.JTextPane txtLogText;
    private javax.swing.JTextField txtMBeanName;
    private javax.swing.JPasswordField txtPassword;
    private javax.swing.JTextField txtUsername;
    // End of variables declaration//GEN-END:variables
}
